package controllers

import java.io.File

import dao._
import javax.inject.{Inject, Singleton}
import org.apache.commons.io.FileUtils
import play.api.libs.json.Json
import play.api.mvc.{AbstractController, ControllerComponents}
import utils.{TableUtils, Utils}

import scala.concurrent.duration.Duration
import scala.concurrent.{Await, ExecutionContext}

@Singleton
class LocationController @Inject()(cc: ControllerComponents,
                                   chloroplastDao: ChloroplastDao,
                                   mtDao:MtDao,
                                   mtgenomeDao:MtgenomeDao,
                                   cpgenomeDao: CpgenomeDao)
                                  (implicit exec: ExecutionContext) extends AbstractController(cc) {

  def getMapData = Action {
    val json = FileUtils.readFileToString(new File(Utils.path, "config/china.json"))
    Ok(Json.parse(json))
  }


  def cpMapPage = Action { implicit request =>
    Ok(views.html.english.chloroplast.map("0"))
  }

  def getCpWorldData = Action.async { implicit request =>
    val mmap = TableUtils.mmap
    val maxmap = TableUtils.maxmap
    chloroplastDao.getAll.map { cp =>
      val position = cp.flatMap(_.position.replaceAll(" and ", "、").split("、")).flatMap { x =>
        if (maxmap.getOrElse(x.trim, "") != "") {
          maxmap(x.trim).map(_._3)
        } else {
          if (x.indexOf(":") != -1) {
            val w = mmap.filter(_._2 == x.split(":").last.trim).map(_._3)
            if (w.isEmpty) {
              mmap.filter(_._2 == x.split(":").head.trim).map(_._3)
            } else {
              w
            }
          } else {
            mmap.filter(_._2 == x.trim).map(_._3)
          }
        }
      }.groupBy(x => x).map { x =>
        Json.obj("key" -> x._1, "num" -> x._2.length)
      }
      Ok(Json.toJson(position))
    }
  }

  def getMtWorldData = Action.async { implicit request =>
    val mmap = TableUtils.mmap
    val maxmap = TableUtils.maxmap
    mtDao.getAll.map { mt =>
      val position = mt.flatMap(_.position.replaceAll(" and ", "、").split("、")).flatMap { x =>
        if (maxmap.getOrElse(x.trim, "") != "") {
          maxmap(x.trim).map(_._3)
        } else {
          if (x.indexOf(":") != -1) {
            val w = mmap.filter(_._2 == x.split(":").last.trim).map(_._3)
            if (w.isEmpty) {
              mmap.filter(_._2 == x.split(":").head.trim).map(_._3)
            } else {
              w
            }
          } else {
            mmap.filter(_._2 == x.trim).map(_._3)
          }
        }
      }.groupBy(x => x).map { x =>
        Json.obj("key" -> x._1, "num" -> x._2.length)
      }
      Ok(Json.toJson(position))
    }
  }


  def getCpInfoByLocation(location: String) = Action.async {
    val lo = TableUtils.mmap.find(_._3 == location).get._2
    chloroplastDao.getAll.map { y =>
      val json = y.filter(_.position.indexOf(lo) != -1).flatMap { cp =>
        val row = Await.result(cpgenomeDao.getByCpID(cp.id),Duration.Inf)
         row.map { z =>
          Json.obj("id" -> z.id, "geneid" -> ("0" * (5 - z.id.toString.length) + z.id),
            "name" -> z.name,
            "imgid" -> cp.id,
            "species" -> cp.species, "bp" -> cp.bp,
            "configuration" -> cp.configuration, "submiter" -> cp.submiter)
        }
      }
      Ok(Json.toJson(json))
    }
  }



  def getMtInfoByLocation(location: String) = Action.async {
    val lo = TableUtils.mmap.find(_._3 == location).get._2
    mtDao.getAll.map { y =>
      val json = y.filter(_.position.indexOf(lo) != -1).flatMap { mt =>
        val row = Await.result(mtgenomeDao.getByMtId(mt.id.toString),Duration.Inf)
        row.map { z =>
          Json.obj("id" -> z.id, "geneid" -> ("0" * (5 - z.id.toString.length) + z.id),
            "name" -> z.name,
            "imgid" -> mt.id,
            "species" -> mt.species,
            "location" -> mt.position, "bp" -> mt.bp,
            "configuration" -> mt.configuration, "submiter" -> mt.submiter)
        }
      }
      Ok(Json.toJson(json))
    }
  }

}
